// ---------------------------------------------------
// script for gitbook game
// ---------------------------------------------------
// version 0.2
// ---------------------------------------------------
// author guoxiaomi
// email iamguoxiaomi@sina.com
// ---------------------------------------------------

// ---------------------------------------------------
// global vars
// ---------------------------------------------------
var $db;
var $url;
var $hide;
var $db_name;

$db = {};
$url = "http://www.gxmatmars.com/games/gitbook.php";


// ---------------------------------------------------
// fetch data from server, return in json format
// ---------------------------------------------------
function connect(db_name, refresh_interval = 3) {
    rewrite_href();
    if (getCookie("checkcode") == "") {
        set_checkcode();
    }
    $db_name = db_name.replace(/\//, "." + getCookie("checkcode") + "/");
    $(document).ready(refresh());
    if (refresh_interval > 0) {
        setInterval("refresh()", refresh_interval * 1000);
    }
}

function refresh() {
    $.getJSON($url + "?jsoncallback=?", {"load": $db_name},
        function(json) {refresh_variant(json);}
    );
}

function refresh_variant(json) {
    $db = json;
    $(".variant").remove();
    replace_html();
    if ($db["_hide_"]) {
        var match;
        for (i = 0; i < $db["_hide_"].length; i++) {
            match = $db["_hide_"][i].match(/\$\{(.+)\}/);
            if (match) {
                $db["_hide_"].concat($db[match]);
            }
        }
        hide_contents($db["_hide_"]);
    }
}

// ---------------------------------------------------
// with dict given, replace vars in html text
// convert text in this style: ${key} to value
// auto convert array
// ---------------------------------------------------
function replace_html() {
    var old_html;
    var new_html;
    // if first vars in src is array, new images
    $("img").each(function(){
        var src = $(this).attr("src");
        var alt = $(this).attr("alt");
        var match = src.match(/\$\{(.+)\}/);
        if (!match) return;
        arr = [].concat($db[match[1]]);
        for (i = 0; i < arr.length; i++) {
            $(this).after(
                ('<img class="variant" src="new_src" alt="' + alt + '">')
                .replace('new_src', src.replace(match[0], arr[i]))
            );
        }
        $(this).hide();
    });
    // normal replace
    // if replaced by array, join array with <br/>
    $("p").each(function(){
        old_html = $(this).html();
        new_html = old_html.replace(/\$\{(.+)\}/g,
            function(word, key) {
                return [].concat($db[key]).join("<br/>");
            }
        );
        if (new_html != old_html) {
            $(this).after(
                '<p class="variant">' + new_html + '</p>'
            );
            $(this).hide();
        }
    });
    // if replaced by array, add more li after self
    $("li").each(function(){
        old_html = $(this).html();
        new_html = old_html.replace(/\$\{(.+)\}/g,
            function(word, key) {
                return [].concat($db[key]).join("</li><li>");
            }
        );
        if (new_html != old_html) {
            // use after && remove
            $(this).after(
                ('<li>' + new_html + '</li>')
                .replace(/<li>/g, '<li class="variant">')
            );
            $(this).hide();
        }
    });
    // td, auto add tr if there's enough columns
    var arr;
    $("table").each(function(){
        arr = [];
        $(this).find("th").each(function(){
            arr.push($(this).attr("style"));
        });

        $(this).find("td").each(function(){
            old_html = $(this).html();
            new_html = old_html.replace(/\$\{(.+)\}/g,
                function(word, key) {
                    if (typeof $db[key] != "object") {
                        return $db[key];
                    } else {
                        var td_arr = [].concat($db[key]).join("</td><td>").split("</td><td>");
                        var ret = "";
                        for (i = 0; i < td_arr.length; i++) {
                            ret += '<td style="' + arr[i % arr.length] + '">';
                            ret += td_arr[i] + "</td>";
                            if ((i + 1) % arr.length == 0 && i < td_arr.length - 1) {
                                ret += "</tr><tr>";
                            }
                        }
                        return ret;
                    }
                }
            );
            if (new_html != old_html) {
                // cannot find td in new html, use normal replace
                if (!new_html.match("/td><td")) {
                    $(this).after('<td class="variant">' + new_html + '</td>');
                    // $(this).html(new_html);
                    $(this).hide();
                } else {
                    $(this).parent().after(
                        ("<tr>" + new_html + "</tr>")
                        .replace(/<tr>/g, '<tr class="variant">')
                    );
                    $(this).parent().hide();
                }
            }
        });
    });
}

// ---------------------------------------------------
// select all id in given ids
// hide every thing till next same block
// ---------------------------------------------------
function hide_contents(ids) {
    var hi;
    var hj = "h1";
    for (i = 1; i <= 6; i++) {
        hi = "h" + i ;
        // show all hidden headers and after
        $(hi + ":hidden").show().nextUntil(hj).show();
        for (j = 0; j < ids.length; j++) {
            $(hi + "#" + ids[j]).hide()
            .nextUntil(hj).hide();
        }
        hj = hj + ", h" + (i+1);
    }
}

// ---------------------------------------------------
// change some link a -> javascript functions
// ---------------------------------------------------
function rewrite_href() {
    $("a").each(function(){
        $(this).attr("href", function(index, old_value) {
            if (old_value.substring(0, 3) == "js:") {
                var new_herf;
                new_herf = "javascript:";
                new_herf += old_value.substring(3);
                new_herf += "(";
                new_herf +=  $(this).attr("title").replace(/\\(.)/g, "$1");
                new_herf +=  ")";
                $(this).attr("title", $(this).html());
                return new_herf;
            }
        });
    });
}

// ---------------------------------------------------
// cookies
// ---------------------------------------------------
function set_checkcode() {
    var old = getCookie("checkcode");
    if (!old) old = "0000";
    var code = window.prompt("Input checkcode: ", old);
    if (code) setCookie("checkcode", code, 1);
}

function setCookie(c_name,value,expiredays) {
    var exdate = new Date()
    exdate.setDate(exdate.getDate() + expiredays)
    document.cookie = c_name + "=" + escape(value) +
        ((expiredays == null) ? "" : ";expires=" + exdate.toGMTString())
}

function getCookie(c_name) {
    var c_start, c_end;
    if (document.cookie.length > 0) {
        c_start = document.cookie.indexOf(c_name + "=");
        if (c_start != -1) {
            c_start = c_start + c_name.length + 1;
            c_end = document.cookie.indexOf(";", c_start);
            if (c_end == -1) c_end = document.cookie.length;
            return unescape(document.cookie.substring(c_start, c_end));
        }
    }
    return "";
}

// ---------------------------------------------------
// database
// ---------------------------------------------------
function update(db_name, update_value, force = '0') {
    var key = (db_name) ? $db_name.split("/")[0] + '/' + db_name : $db_name;
    $.post($url, {"update": key, "value": JSON.stringify(update_value), "force": force})
}

function get(key) {
    return $db[key];
}

function set(key, value) {
    $db[key] = value;
    var o = {};
    o[key] = value;
    update(null, o);
}

function add(key, value) {
    value = [].concat(value);
    var arr = get(key);
    if (!arr) arr = [];
    arr.concat(value);

    $db[key] = arr;
    var o = {};
    o['_add_'] = {};
    o['_add_'][key] = value;
    update(null, o);
}

function del(key, value) {
    value = [].concat(value);
    var arr = get(key);
    if (!arr) arr = [];

    var new_arr = [];
    for (i = 0; i < arr.length; i++) {
        if ($.inArray(arr[i], value) == -1) {
            new_arr.push(arr[i]);
        }
    }

    $db[key] = new_arr;
    var o = {};
    o['_del_'] = {}
    o['_del_'][key] = value;
    update(null, o);
}

function judge_condition(condition) {
    if (typeof condition == "function") {
        return condition();
    } else {
        return condition == true;
    }
}

function setif(key, value, condition) {
    if (judge_condition(condition)) set(key, value);
}

function addif(key, value, condition) {
    if (judge_condition(condition)) add(key, value);
}

function delif(key, value, condition) {
    if (judge_condition(condition)) del(key, value);
}

function input(prompt = "") {
    return window.prompt(prompt, "");
}

function p(text) {
    console.log(text);
}